﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ymatou.PerfMonitorClient;
using YmtAuth.Common.Extend;
using YmtAuth.Domain.DomainEvent;
using YmtAuth.Domain.Model.BlacklistUser;
using YmtSystem.CrossCutting;
using YmtSystem.Infrastructure.EventBusService;

namespace YmtAuth.Domain.Model.Safe
{
    /// <summary>
    /// 买家app登录风控验证策略处理
    /// </summary>
    public class BuyerAppSafeHandle
    {
        //检查是否开启买家APP登录风控
        public class CheckEnableSafe : SafeVerifyStrategyBase
        {
            public override AuthSafeHandleCode Execute(
                UserLoginParameter par
                , UserLoginAuthRepository repo
                , AuthSafeConfiguration cfg)
            {
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_App_Open, "1") != "1")
                {
                    YmatouLoggingService.Debug("登录风控-App开关, 【LoginSafe_App_Open】 is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.AllowLogin);
                }
                return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
            }

            public override string ToString()
            {
                return "*BuyerApp-CheckEnableSafe*";
            }
        }
        //TOKEN最后验证时间验证策略
        public class TokenVerify : SafeVerifyStrategyBase
        {
            public override string ToString()
            {
                return "*BuyerApp-TokenVerify*";
            }
            public override AuthSafeHandleCode Execute(
                UserLoginParameter par
                , UserLoginAuthRepository repo
                , AuthSafeConfiguration cfg)
            {
                string desc = String.Empty;
                //用户最后一次IP区域认证检查
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppToken_Check, "1") != "1")
                {
                    desc = String.Format("LoginSafe_AppToken_Check is false");
                    YmatouLoggingService.Debug(
                        "登录风控-用户最后一次IP区域认证, 【LoginSafe_AppToken_Check】 is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify, desc);
                }
                if (string.IsNullOrEmpty(par.Ip))
                {
                    var msg = string.Format("[TokenVerify] 用户{0}IP为空需要身份认证，执行{1}", par.LoginId, AuthSafeHandleCode.NeedIdentityVerify);
                    var authSafeHandleCode = AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.NeedIdentityVerify,
                    AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_IPNotExists, msg);
                    YmatouLoggingService.Debug("登录风控-IP区域检查, {0}, requestId: {1}", msg, par.RequestId);
                    return authSafeHandleCode;
                }            
                var watch = Stopwatch.StartNew();
                var rawIpRearInfo = repo.IpAreaRepo.FindIpAreaInfo(IpAreaInfoAuthEntity.IpConvertToLong(par.Ip));
                watch.Stop();
                if (rawIpRearInfo == null)
                {
                    EventBus.Instance.Publish(new LoginSafeVerifyEvent
                    {
                        UserId = par.UserId,
                        AppSource = par.Source,
                        AuthType = "VerifyIpAreaLastAuthTime",
                        ResponseCode = AuthSafeHandleCode.ContinueNextVerify,
                        LoginId = par.LoginId,
                        LoginIp = par.Ip,
                        Desc = "App端toke最后认证时间检查，原始库不存在IP区域",
                        RunTime = watch.Elapsed.TotalMilliseconds
                    });
                    desc = String.Format("原始库不存在IP {0} 区域,loginId:{1},source:{2}", par.Ip, par.LoginId,
                        par.Source);
                    YmatouLoggingService.Debug("登录风控-用户最后一次IP区域认证, 原始库不存在; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify, desc);
                }
                watch.Restart();
                var lastAuthIpAreaInfo = repo.IpAreaRepo.FindUserLastTokenAuthIpAreaInfo(par.UserId,
                    rawIpRearInfo.Country,
                    rawIpRearInfo.Province, rawIpRearInfo.City);
                watch.Stop();
                if (lastAuthIpAreaInfo == null)
                {
                    EventBus.Instance.Publish(new LoginSafeVerifyEvent
                    {
                        UserId = par.UserId,
                        AppSource = par.Source,
                        AuthType = "VerifyIpAreaLastAuthTime",
                        ResponseCode = AuthSafeHandleCode.ContinueNextVerify,
                        LoginId = par.LoginId,
                        LoginIp = par.Ip,
                        Desc = "最后一次Ip区域认证不存在",
                        RunTime = watch.Elapsed.TotalMilliseconds
                    });

                    desc = String.Format("用户{0}最后一次Ip区域认证不存在", par.LoginId);
                    YmatouLoggingService.Debug("登录风控-用户最后一次IP区域认证, {0}; requestId: {1}", desc, par.RequestId);

                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify, desc);
                }
                if (lastAuthIpAreaInfo.AuthTime == null)
                {
                    desc = String.Format("用户 {0} 最后一次Ip  {1} 区域认证,认证时间为空,执行身份认证", par.LoginId, par.Ip);
                    YmatouLoggingService.Debug("登录风控-用户最后一次IP区域认证, {0}; requestId: {1}", desc, par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.NeedIdentityVerify, desc);
                }
                var subDay = DateTime.Now.Subtract(lastAuthIpAreaInfo.AuthTime.Value).TotalDays;
                var lastDay =
                    cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_PcToken_LastAuthDay, "90")
                        .ConvertToInt32(90);
                var code = subDay >= lastDay
                    ? AuthSafeHandleCode.NeedIdentityVerify
                    : AuthSafeHandleCode.ContinueNextVerify;
                desc = subDay >= lastDay
                    ? String.Format("最后一次Ip区域({0}|{1}|{2})认证时间 {3} 大于等于{4}天，执行身份验证",lastAuthIpAreaInfo.Country,lastAuthIpAreaInfo.Province,lastAuthIpAreaInfo.City, lastAuthIpAreaInfo.AuthTime.Value, lastDay)
                    : String.Format("最后一次Ip区域({0}|{1}|{2})认证时间 {3} 小于{4}天", lastAuthIpAreaInfo.Country, lastAuthIpAreaInfo.Province, lastAuthIpAreaInfo.City,lastAuthIpAreaInfo.AuthTime.Value, lastDay);

                AuthSafeHandleCode res = null;
                if (AuthSafeHandleCode.NeedIdentityVerify == code)
                {
                    res = AuthSafeHandleCode.CreateCode(code
                        , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIpAreaLastAuthTime
                        , desc
                        , YmatouBlacklistUserSpecifications.GetLogin_NeedIdentityVerifyMessage(par.Source));
                }
                else
                {
                    res = AuthSafeHandleCode.CreateCode(code, desc);
                }

                //TODO 发布最后一次IP区域认证时间事件
                EventBus.Instance.Publish(new LoginSafeVerifyEvent
                {
                    UserId = par.UserId,
                    AppSource = par.Source,
                    AuthType = "VerifyIpAreaLastAuthTime",
                    ResponseCode = res.SubCode,
                    LastAuthTime = lastAuthIpAreaInfo.AuthTime.Value,
                    LoginId = par.LoginId,
                    LoginIp = par.Ip,
                    Desc = desc,
                    RunTime = watch.Elapsed.TotalMilliseconds
                });
                YmatouLoggingService.Debug("登录风控-用户最后一次IP区域认证, {0}; requestId: {1}", desc, par.RequestId);
                return res;
            }
        }      
        //登录失败历史检查
        public class LoginFailHistoryVerify : SafeVerifyStrategyBase
        {
            public override string ToString()
            {
                return "*BuyerApp-LoginFailHistoryVerify*";
            }
            public override AuthSafeHandleCode Execute(UserLoginParameter par, UserLoginAuthRepository repo,
                AuthSafeConfiguration cfg)
            {
                //验证是否开启登录密码错误历史检查
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppLoginPas_Check, "1") != "1")
                {
                    YmatouLoggingService.Debug(
                        "LoginFailHistoryVerify,LoginSafe_PcLoginPas_Check is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
                }
                var pasCfg = cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppLoginPas_CheckSpec, "-10,6");
                var splitCfg = pasCfg.Split(new char[] {','});
                if (splitCfg == null || splitCfg.Length != 2)
                {
                    splitCfg = new string[] {"-10", "6"};
                    YmatouLoggingService.Debug("buyer app login fail not set cfg,use default cfg");
                }
                var loginFailTimeMinutes = splitCfg[0].ConvertToInt32(-10);
                var loginFailCount = splitCfg[1].ConvertToInt32(6);

                return CommonStrategy.loginPasswordHistoryVerify(par, repo, cfg, loginFailTimeMinutes, loginFailCount);
            }
        }
        //设备号认证状态检查
        public class DeviceStatusVerify : SafeVerifyStrategyBase
        {
            public override string ToString()
            {
                return "*BuyerApp-DeviceStatusVerify*";
            }
            public override AuthSafeHandleCode Execute(UserLoginParameter par, UserLoginAuthRepository repo,
                AuthSafeConfiguration cfg)
            {
                //检查开关
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_ExistsCheck, "1") != "1")
                {
                    YmatouLoggingService.Debug(
                        "DeviceVerify,LoginSafe_AppDevice_ExistsCheck is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
                }
                //如果未收集到登录设备号参数     
                AuthSafeHandleCode checkDeviceParIsExists = CheckDeviceParIsExists(par, cfg);
                if (checkDeviceParIsExists.Code == AuthSafeHandleCode.NeedIdentityVerify) return checkDeviceParIsExists;  
                //检查是否常用设备             
                var statusCode = VerifyDeviceStatus(par, repo, cfg);
                YmatouLoggingService.Debug("DeviceId verify result: {0}, {1}, requestId: {2}",
                    statusCode.Code, statusCode.Message, par.RequestId);
                return statusCode;
            }         
            //验证设备号
            private AuthSafeHandleCode VerifyDeviceStatus(UserLoginParameter par, UserLoginAuthRepository repo,
                AuthSafeConfiguration cfg)
            {
                var code = 0;
                var desc = "";
                var watch = Stopwatch.StartNew();
                var decvice = repo.DeviceRepo.FindUserDevice(par.UserId, par.DeviceId);
                watch.Stop();
                //如果认证库设备号不存在
                if (decvice == null)
                {
                    code = cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_NotExists, "100").ConvertToInt32(100);
                    desc = String.Format("该设备号不存在，执行Code_{0}", code);

                    AuthSafeHandleCode res = null;
                    if (AuthSafeHandleCode.NeedIdentityVerify == code)
                    {
                        res = AuthSafeHandleCode.CreateCode(code
                            , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindDevice
                            , desc
                            , "请执行身份验证");
                    }
                    else
                        res = AuthSafeHandleCode.CreateCode(code, desc);

                    EventBus.Instance.Publish(new LoginSafeVerifyEvent
                    {
                        UserId = par.UserId,
                        AppSource = par.Source,
                        AuthType = "UserDeviceExistsCheck",
                        ResponseCode = res.SubCode,
                        LoginId = par.LoginId,
                        LoginIp = par.Ip,
                        Desc = String.Format("{0}", desc),
                        DeviceId = par.DeviceId,
                        ClientId = par.AppClientId,
                        RunTime = watch.Elapsed.TotalMilliseconds
                    });

                    return res;
                }
                else
                {
                    //否则验证设备号认证状态
                    return VerifyDeviceStatus(par, decvice, cfg);
                }
            }
            //设备号状态验证
            public AuthSafeHandleCode VerifyDeviceStatus(UserLoginParameter par, UserDeviceAuthEntity device,
                AuthSafeConfiguration cfg)
            {
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_StatusCheck, "1") != "1")
                {
                    YmatouLoggingService.Debug("登录风控-设备号状态验证, 【LoginSafe_AppDevice_StatusCheck】 is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify, "未开启设备号验证");
                }
                var watch = Stopwatch.StartNew();
                var code = device.AuthIsSuccess()
                    ? cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_AuthSuccessAction, "200")
                        .ConvertToInt32(AuthSafeHandleCode.ContinueNextVerify)
                    : cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_AuthFailAction, "100")
                        .ConvertToInt32(AuthSafeHandleCode.NeedIdentityVerify);
                var desc = device.AuthIsSuccess()
                    ? String.Format("设备号认证成功，执行Code_{0}", code)
                    : String.Format("设备号未认证或者认证失败，执行Code_{0}", code);
                watch.Stop();

                AuthSafeHandleCode res = null;
                if (AuthSafeHandleCode.NeedIdentityVerify == code)
                {
                    res = AuthSafeHandleCode.CreateCode(code
                        , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyDeviceStatus
                        , desc
                        , YmatouBlacklistUserSpecifications.GetLogin_NeedIdentityVerifyMessage(par.Source));
                }
                else
                {
                    res = AuthSafeHandleCode.CreateCode(code, desc);
                }

                EventBus.Instance.Publish(new LoginSafeVerifyEvent
                {
                    UserId = par.UserId,
                    AppSource = par.Source,
                    AuthType = "VerifyDeviceStatus",
                    ResponseCode = res.SubCode,
                    LoginId = par.LoginId,
                    LoginIp = par.Ip,
                    Desc = String.Format("{0}", desc),
                    DeviceId = par.DeviceId,
                    ClientId = par.AppClientId,
                    RunTime = watch.Elapsed.TotalMilliseconds
                });

                return res;
            }
        }
        //设备号黑名单检查
        public class DeviceBlacklistVerify : SafeVerifyStrategyBase
        {
            public override string ToString()
            {
                return "*BuyerApp-DeviceBlacklistVerify*";
            }
            public override AuthSafeHandleCode Execute(UserLoginParameter par, UserLoginAuthRepository repo,
                AuthSafeConfiguration cfg)
            {
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppBlacklist_Check, "1") != "1")
                {
                    YmatouLoggingService.Debug("登录风控-设备号黑名单, 【LoginSafe_AppBlacklist_Check】 is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
                }
                //如果未收集到登录设备号参数  
                AuthSafeHandleCode checkDeviceParIsExists = CheckDeviceParIsExists(par, cfg);
                if (checkDeviceParIsExists.Code == AuthSafeHandleCode.NeedIdentityVerify) return checkDeviceParIsExists;  
            
                var watch = Stopwatch.StartNew();
                var blackListdevice = repo.IpBlackListRepo.FindOne(YmatouBlacklistUserSpecifications.MatchDeviceId(par.DeviceId));
                watch.Stop();
                var code = AuthSafeHandleCode.ContinueNextVerify;
                var desc = String.Format("此设备号 {0} 不在黑名单,执行下个安全认证", par.DeviceId);
                //如果是黑名单且禁止登录时间未到期,则（根据配置）执行身份验证或者拒绝登录
                DateTime? expiredTime = null;
                if (blackListdevice != null)
                {
                    if (blackListdevice.IsDisableRequest())
                    {
                        code =
                            cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppBlacklist_BlacklistAction, "100")
                                .ConvertToInt32(AuthSafeHandleCode.NeedIdentityVerify);
                        desc = String.Format("该设备号为黑名单，执行Code_{0}", code);
                    }
                    else
                    {
                        code = AuthSafeHandleCode.ContinueNextVerify;
                        desc = "此设备号在黑名单,锁定时间已超时,执行下个安全认证";
                    }

                    expiredTime = blackListdevice.ExpiredTime.ToLocalTime();
                }

                AuthSafeHandleCode res = null;
                if (AuthSafeHandleCode.NeedIdentityVerify == code)
                {
                    res = AuthSafeHandleCode.CreateCode(code
                        , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyBlackDevice
                        , desc
                        , YmatouBlacklistUserSpecifications.GetLogin_NeedIdentityVerifyMessage(par.Source));
                }
                else
                {
                    res = AuthSafeHandleCode.CreateCode(code, desc);
                }

                //TODO 发布设备号黑名单事件
                EventBus.Instance.Publish(new LoginSafeVerifyEvent
                {
                    UserId = par.UserId,
                    AppSource = par.Source,
                    AuthType = "DeviceBlacklistVerify",
                    ResponseCode = res.SubCode,
                    ExpiredTime = expiredTime,
                    LoginId = par.LoginId,
                    LoginIp = par.Ip,
                    Desc = String.Format("{0}", desc),
                    DeviceId = par.DeviceId,
                    ClientId = par.AppClientId,
                    RunTime = watch.Elapsed.TotalMilliseconds
                });

                YmatouLoggingService.Debug("登录风控-设备号黑名单验证, {0}, LoginId: {1}, key(ClientId, DeviceId): {2}, requestId: {3}", desc, par.LoginId, par.DeviceId, par.RequestId);

                return res;
            }
        }
        //常用IP区域检查(买家APP登录风控最后一个策略)
        public class IpAreaVerify : SafeVerifyStrategyBase
        {
            public override string ToString()
            {
                return "*BuyerApp-IpAreaVerify*";
            }
            public override bool IsLastStrategy{get { return true; }}
            public override AuthSafeHandleCode Execute(
                UserLoginParameter par
                , UserLoginAuthRepository repo
                , AuthSafeConfiguration cfg)
            {               
                //检查是否开启IP区域存在性验证
                if (cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppIp_ExistsCheck, "1") != "1")
                {
                    YmatouLoggingService.Debug("登录风控-IP区域检查, 【LoginSafe_PcIp_ExistsCheck】 is false; requestId: {0}", par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
                }
                if (string.IsNullOrEmpty(par.Ip))
                {                   
                    var msg = string.Format("用户{0}IP为空需要身份认证，执行{1}", par.LoginId, AuthSafeHandleCode.NeedIdentityVerify);
                    var authSafeHandleCode = AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.NeedIdentityVerify,
                    AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_IPNotExists, msg);
                    YmatouLoggingService.Debug("登录风控-IP区域检查, {0}, requestId: {1}", msg, par.RequestId);
                    return authSafeHandleCode;
                }               
                //获取IP区域原始数据,不存在则不需要身份验证
                var watch = Stopwatch.StartNew();
                var ipAreaRawInfo = repo.IpAreaRepo.FindIpAreaInfo(IpAreaInfoAuthEntity.IpConvertToLong(par.Ip));
                watch.Stop();
                if (ipAreaRawInfo == null)
                {
                    //TODO 发布原始IP区域数据不存在事件
                    EventBus.Instance.Publish(new LoginSafeVerifyEvent
                    {
                        UserId = par.UserId,
                        AppSource = par.Source,
                        AuthType = "IpAreaVerify",
                        ResponseCode = AuthSafeHandleCode.RawIpNotFind,
                        LoginId = par.LoginId,
                        LoginIp = par.Ip,
                        Desc = "IP库原始数据不存在,执行下个安全认证",
                        RunTime = watch.Elapsed.TotalMilliseconds
                    });
                    using (var mm = MethodMonitor.New("IpAreaRaw_NotFind"))
                    {
                    }
                    YmatouLoggingService.Debug("登录风控-IP区域检查, IP库原始数据不存在,执行下个安全认证, LoginId: {0}, ip: {1}, requestId: {2}", par.LoginId,
                        par.Ip, par.RequestId);
                    return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
                }
                //获取IP区域认证数据,不存在则需要身份验证 
                watch.Restart();
                var ipAreaInfo = repo.IpAreaRepo.FindAreaInfoAuthEntity(par.UserId, ipAreaRawInfo.Country,
                ipAreaRawInfo.Province, ipAreaRawInfo.City);
                watch.Stop();                 
                if (ipAreaInfo == null)
                {                    
                    var desc = string.Format("IP区域不存在需要身份认证,执行Code_{0}", AuthSafeHandleCode.NeedIdentityVerify);
                    YmatouLoggingService.Debug("登录风控-IP区域检查, {0}, requestId: {1}", desc, par.RequestId);
                    var authSafeHandleCode = AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.NeedIdentityVerify
                        , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindIpArea
                        , desc);
                    EventBus.Instance.Publish(new LoginSafeVerifyEvent
                    {
                        UserId = par.UserId,
                        AppSource = par.Source,
                        AuthType = "IpAreaVerify",
                        ResponseCode = authSafeHandleCode.SubCode,
                        IpArea = ipAreaRawInfo.GetArea(),
                        LoginId = par.LoginId,
                        LoginIp = par.Ip,
                        Desc = string.Format("{0}", desc),
                        RunTime = watch.Elapsed.TotalMilliseconds
                    });
                    return authSafeHandleCode;
                }
                else
                {
                  return VerifyIPAreaStatus(par, cfg, ipAreaInfo);
                }             
            }
            private AuthSafeHandleCode VerifyIPAreaStatus(UserLoginParameter par, AuthSafeConfiguration cfg,
               IpAreaInfoAuthEntity ipAreaInfo)
            {
                //IP 区域未认证，认证失败需要用户身份验证             
                var code = 0;
                var desc = "";
                if (!ipAreaInfo.AuthIsSuccess())
                {
                    code = AuthSafeHandleCode.NeedIdentityVerify;
                    desc = string.Format("IP区域认证未认证需要认证身份，执行Code_{0}", code);
                }
                else
                {
                    code = AuthSafeHandleCode.AllowLogin;
                    desc = string.Format("IP区域认证成功，执行Code_{0}", code);
                }              
                AuthSafeHandleCode res = null;
                if (AuthSafeHandleCode.NeedIdentityVerify == code)
                {
                    res = AuthSafeHandleCode.CreateCode(code
                        , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_VerifyIPAreaStatus
                        , desc);
                }
                else
                {
                    res = AuthSafeHandleCode.CreateCode(code, desc);
                }
                EventBus.Instance.Publish(new LoginSafeVerifyEvent
                {
                    UserId = par.UserId,
                    AppSource = par.Source,
                    AuthType = "VerifyIPAreaStatus",
                    ResponseCode = res.SubCode,
                    IpArea = ipAreaInfo.GetArea(),
                    LoginId = par.LoginId,
                    LoginIp = par.Ip,
                    Desc = string.Format("{0}", desc),
                    RunTime = 0
                });
                YmatouLoggingService.Debug("登录风控-IP区域状态验证, {0}; LoginId: {1}, Ip: {2}, AuthStatus: {3}, requestId: {4}", desc, par.LoginId, par.Ip, ipAreaInfo.AuthStatus, par.RequestId);
                return res;
            }
        }
        //检查是否获取到用户登录设备号
        private static AuthSafeHandleCode CheckDeviceParIsExists(UserLoginParameter par, AuthSafeConfiguration cfg)
        {
            if (!par.DeviceId.IsEmpty())
                return AuthSafeHandleCode.CreateCode(AuthSafeHandleCode.ContinueNextVerify);
            var code = cfg.SafeCfg.TryGet(SafeCfgKey.LoginSafe_AppDevice_NotExists, "100").ConvertToInt32(100);
            var desc = String.Format("user device is empty，ResponseCode:{0}", code);
            AuthSafeHandleCode res = null;
            if (AuthSafeHandleCode.NeedIdentityVerify == code)
            {
                res = AuthSafeHandleCode.CreateCode(code
                    , AuthSafeHandleSubCode.NeedIdentityVerify_LoginSafe_CannotFindDevice
                    , desc);
            }
            else
            {
                res = AuthSafeHandleCode.CreateCode(code, desc);
            }

            EventBus.Instance.Publish(new LoginSafeVerifyEvent
            {
                UserId = par.UserId,
                AppSource = par.Source,
                AuthType = "CheckDeviceParIsExists",
                ResponseCode = res.SubCode,
                DeviceId = par.DeviceId,
                LoginId = par.LoginId,
                LoginIp = par.Ip,
                Desc = desc,
                RunTime = 0
            });

            return res;
        }
    }
}
